﻿using Microsoft.VisualStudio.TestTools.UnitTesting;

using DatabaseGroup.SSIS.SourceAdapters.Parser;

namespace DatabaseGroup.UnitTests.SSIS.SourceAdapters.Parser
{
    [TestClass()]
    public class RowParserTest
    {
        private TestContext _testContextInstance;

        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        [TestMethod()]
        [ExpectedException(typeof(System.ArgumentNullException), "Expected ArgumentNullException to be thrown when ctor called with null args")]
        public void RowParser_ConstructorWithNullArgs_ThrowArgumentNullException()
        {          
            RowParser target = new RowParser(null, null, null);
        }

        [TestMethod()]
        [ExpectedException(typeof(System.ArgumentNullException), "Expected ArgumentNullException to be thrown when called with null 1st arg")]
        public void ParseNextRow_Null1stArg_ThrowArgumentNullException()
        {
            RowData rowData = new RowData();
            RowParser target = new RowParser(string.Empty, ",", string.Empty);
            target.ParseNextRow(null, rowData);
        }

        [TestMethod()]
        public void ParseNextRow_ParseTwoSimpleRows_ReturnExpectedRowData()
        {
            RowData rowData = new RowData();
            IFileReader reader = FileReaderTest.GetReader("A,B,C\r\n1,2,3");
            RowParser target = new RowParser(",", "\r\n", string.Empty);

            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, "A,B,C\r\n", new string[] { "A", "B", "C" });
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, "1,2,3", new string[] { "1", "2", "3" });
        }

        [TestMethod()]
        public void ParseNextRow_ParseTextQualifiedRow_ReturnExpectedRowData()
        {
            RowData rowData = new RowData();
            IFileReader reader = FileReaderTest.GetReader("\"A,B\r\n\",C\r\n1,2,3");
            RowParser target = new RowParser(string.Empty, "\r\n", "\"");

            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, "\"A,B\r\n\",C\r\n", new string[] { "A,B\r\n,C" });
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, "1,2,3", new string[] { "1,2,3" });
        }

        [TestMethod()]
        public void ParseNextRow_ParseSimpleUnevenRows1_ReturnExpectedRowData()
        {
            RowData rowData = new RowData();
            IFileReader reader = FileReaderTest.GetReader("A,B\r\n1,2,3");
            RowParser target = new RowParser(",", "\r\n", string.Empty);

            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "A", "B"});
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "1", "2", "3" });
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[0]);
        }

        [TestMethod()]
        public void ParseNextRow_ParseSimpleUnevenRows2_ReturnExpectedRowData()
        {
            RowData rowData = new RowData();
            IFileReader reader = FileReaderTest.GetReader("A,B,C,D\r\n1,2,3");
            RowParser target = new RowParser(",", "\r\n", "\"");

            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "A", "B", "C", "D" });
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "1", "2", "3" });
        }

        [TestMethod()]
        public void ParseNextRow_ParseTextQualifiedRowWithError_ReturnExpectedRowData()
        {
            RowData rowData = new RowData();
            IFileReader reader = FileReaderTest.GetReader("A,\"B\" \r\n1,2,3");
            RowParser target = new RowParser(",", "\r\n", "\"");

            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "A", "B "});
            target.ParseNextRow(reader, rowData);
            RowDataTest.VerifyParsedRow(rowData, new string[] { "1", "2", "3" });
        }

        [TestMethod()]
        [ExpectedException(typeof(RowColumnNumberOverflow), "Expected RowColumnNumberOverflow to be thrown when RowParser used with row with too many columns")]
        public void ParseNextRow_ParseRowWithTooManyColumns_ThrowRowColumnNumberOverflow()
        {
            RowData rowData = new RowData();
            // It will repeat the given string up to 8000 characters and that 
            // will pass the maximum number of columns.
            IFileReader reader = new FileReaderTestImpl("ABC,", 2000*4);
            RowParser target = new RowParser(",", "\r\n", string.Empty);

            target.ParseNextRow(reader, rowData);
        }
    }
}
